package com.bolt.convention.data;

import com.bolt.common.convert.ConverterRegistry;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * Created by Administrator on 2017/8/17.
 */
public class Record extends LinkedHashMap<String, Object> {
    private static final long serialVersionUID = -2056047758732968455L;
    private final ConverterRegistry converterRegistry = ConverterRegistry.getInstance();

    public <T> T getObjectByType(String key, Class<T> cls) {
        Object obj = get(key);
        if (obj == null) {
            return null;
        }
        if (obj.getClass() == cls) {
            return (T) get(key);
        } else {
            return getObj(obj, cls);
        }
    }

    private <T> T getObj(Object obj, Class<T> cls) {
        try {
            return converterRegistry.convert(cls, obj);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }



    // 基本类型
    public int getint(String key) {
        return getObjectByType(key, int.class);
    }

    public float getfloat(String key) {
        return getObjectByType(key, float.class);
    }

    public double getdouble(String key) {
        return getObjectByType(key, double.class);
    }

    public long getlong(String key) {
        return getObjectByType(key, long.class);
    }

    public boolean getboolean(String key) {
        return getObjectByType(key, boolean.class);
    }

    // 以下对象类型
    public Integer getInteger(String key) {
        return getObjectByType(key, Integer.class);
    }

    public Long getLong(String key) {
        return getObjectByType(key, Long.class);
    }

    public Double getDouble(String key) {
        return getObjectByType(key, Double.class);
    }

    public Boolean getBoolean(String key) {
        return getObjectByType(key, Boolean.class);
    }

    public Float getFloat(String key) {
        return getObjectByType(key, Float.class);
    }

    public String getString(String key) {
        return getObjectByType(key, String.class);
    }

    public BigDecimal getBigDecimal(String key) {
        return getObjectByType(key, BigDecimal.class);
    }

    public BigInteger getBigInteger(String key) {
        return getObjectByType(key, BigInteger.class);
    }

    public Date getDate(String key) {
        return getObjectByType(key, Date.class);
    }

    public Timestamp getTimestamp(String key) {
        return getObjectByType(key, Timestamp.class);
    }

    public java.sql.Date getSqlDate(String key) {
        return getObjectByType(key, java.sql.Date.class);
    }

    public byte[] getBytes(String key) {
        return getObjectByType(key, byte[].class);
    }

    @SuppressWarnings("rawtypes")
    public <T> List<T> getList(String key, Class<T> cls) {
        Object obj = get(key);
        if (obj == null) {
            return null;
        }
        if (obj instanceof List) {

            List lst = (List) obj;
            if (lst.size() > 0) {
                if (lst.get(0).getClass() == cls) {
                    return lst;
                } else {
                    List<T> newLst = new ArrayList<T>();
                    for (Object object : lst) {
                        newLst.add(getObj(object, cls));
                    }
                    return newLst;
                }
            }
        }
        if (obj.getClass().isArray()) {
            List<T> newLst = new ArrayList<T>();
            int length = Array.getLength(obj);
            if (length > 0) {
                if (Array.get(obj, 0).getClass() == cls) {
                    for (int i = 0; i < length; i++) {
                        newLst.add((T) Array.get(obj, i));
                    }
                } else {
                    for (int i = 0; i < length; i++) {
                        newLst.add(getObj(Array.get(obj, i), cls));
                    }
                }
            }
            return newLst;
        }
        List<T> newLst = new ArrayList<T>(1);
        if (obj.getClass() == cls) {
            newLst.add((T) obj);
            return newLst;
        } else {
            newLst.add(getObj(obj, cls));
            return newLst;
        }
    }
}
